package com.shaozi.nc.data.mongodao;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;
import com.shaozi.data.mongo.dao.SZMongoBaseDao;
import com.shaozi.lib.throwable.SzException;
import com.shaozi.nc.data.model.GroupMemberRelationModel;

@Repository("groupMemberRelationMDao")
public class GroupMemberRelationMDao extends SZMongoBaseDao<GroupMemberRelationModel> {
	@Autowired
	public GroupMemberRelationMDao(MongoTemplate shaoziTemplate) {
		super(shaoziTemplate);
	}

	private Logger logger = Logger.getLogger(GroupMemberRelationMDao.class);

	public void insertDocument(GroupMemberRelationModel model, String compId) throws SzException {
		if (model.getCreatTime() == null) {
			model.setCreatTime(System.currentTimeMillis());
		}

		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(model.getGroupId())
				.and(GroupMemberRelationModel.FIELDNAME_userId).is(model.getUserId());
		Query query = new Query(c);
		Update update = new Update();
		update.set(GroupMemberRelationModel.FIELDNAME_creatTime, model.getLastUpdateTime());
		update.set(GroupMemberRelationModel.FIELDNAME_lastUpdateTime, model.getLastUpdateTime());
		update.set(GroupMemberRelationModel.FIELDNAME_delState, GroupMemberRelationModel.STATE_USING);
		getMongoTemplate().upsert(query, update, getCollectionName(compId));
	}

	public void delAccountIds(String compId, String[] accountIds, String groupId, long lastUpdateTime, byte delState)
			throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(groupId);
		c.and(GroupMemberRelationModel.FIELDNAME_userId).in(accountIds);// 已验证
		c.and(GroupMemberRelationModel.FIELDNAME_delState).is(GroupMemberRelationModel.STATE_USING);
		Query query = new Query(c);

		Update update = new Update();
		update.set(GroupMemberRelationModel.FIELDNAME_delState, delState);
		update.set(GroupMemberRelationModel.FIELDNAME_lastUpdateTime, lastUpdateTime);
		getMongoTemplate().updateMulti(query, update, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	public GroupMemberRelationModel get(String compId, String groupId, String uid) throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(groupId)
				.and(GroupMemberRelationModel.FIELDNAME_userId).is(uid);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).is(GroupMemberRelationModel.STATE_USING);
		Query query = new Query();
		query.addCriteria(c);
		return getMongoTemplate().findOne(query, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	/**
	 * 获取用户ID列表
	 * 
	 * @param compId
	 * @param groupId
	 * @return
	 * @throws SzException
	 */
	public List<Integer> getMemberUids(String compId, String groupId) throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(groupId);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).is(GroupMemberRelationModel.STATE_USING);
		Query query = new Query(c);
		query.fields().include(GroupMemberRelationModel.FIELDNAME_userId);
		List<GroupMemberRelationModel> models = getMongoTemplate().find(query, GroupMemberRelationModel.class,
				getCollectionName(compId));

		List<Integer> ret = new ArrayList<Integer>(models.size());
		for (GroupMemberRelationModel m : models) {
			try {
				ret.add(Integer.parseInt(m.getUserId()));
			} catch (NumberFormatException e) {
				logger.error(SzException.getStackMessage(e));
			}
		}
		return ret;
	}

	/**
	 * 返回:退出或解散的群ID列表
	 * 
	 * @param compId
	 * @param uid
	 * @param fromTime
	 * @return
	 * @throws SzException
	 */
	public List<String> getOutQuitGroupIds(String compId, String uid, long fromTime) throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_userId).is(uid);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).ne(GroupMemberRelationModel.STATE_USING)
				.and(GroupMemberRelationModel.FIELDNAME_lastUpdateTime).gte(fromTime);

		Query query = new Query();
		query.addCriteria(c);
		return getMongoTemplate().getCollection(getCollectionName(compId))
				.distinct(GroupMemberRelationModel.FIELDNAME_groupId, query.getQueryObject());
	}

	/**
	 * 加载从lastUpdateTime时间启的删除的列表
	 * 
	 * @param compId
	 * @param userId
	 * @param lastUpdateTime
	 * @return
	 * @throws SzException
	 */
	public List<GroupMemberRelationModel> loadLastDeleteRelation(String compId, String userId, long lastUpdateTime)
			throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_userId).is(userId);
		c.and(GroupMemberRelationModel.FIELDNAME_lastUpdateTime).gt(lastUpdateTime);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).ne(GroupMemberRelationModel.STATE_USING);
		Query query = new Query();
		query.addCriteria(c);
		query.fields().include(GroupMemberRelationModel.FIELDNAME_groupId)
				.include(GroupMemberRelationModel.FIELDNAME_delState)
				.include(GroupMemberRelationModel.FIELDNAME_lastUpdateTime);
		query.with(new Sort(new Sort.Order(Direction.DESC, GroupMemberRelationModel.FIELDNAME_lastUpdateTime)));
		return getMongoTemplate().find(query, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	public List<GroupMemberRelationModel> loadRelation(String compId, String userId) throws SzException {
		if (StringUtils.isEmpty(compId))
			return null;
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_userId).is(userId);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).is(GroupMemberRelationModel.STATE_USING);
		Query query = new Query();
		query.addCriteria(c);
		return getMongoTemplate().find(query, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	public List<GroupMemberRelationModel> loadDeletedRelation(String compId, String userId, long fromTimestamp)
			throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_userId).is(userId);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).ne(GroupMemberRelationModel.STATE_USING);
		c.and(GroupMemberRelationModel.FIELDNAME_lastUpdateTime).gt(fromTimestamp);
		Query query = new Query();
		query.addCriteria(c);
		return getMongoTemplate().find(query, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	public List<GroupMemberRelationModel> loadRelationByGroupId(String compId, String groupId) throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(groupId);
		c.and(GroupMemberRelationModel.FIELDNAME_delState).is(GroupMemberRelationModel.STATE_USING);
		Query query = new Query();
		query.addCriteria(c);
		return getMongoTemplate().find(query, GroupMemberRelationModel.class, getCollectionName(compId));
	}

	public void dismissGroup(String compId, String groupId) throws SzException {
		Criteria c = new Criteria(GroupMemberRelationModel.FIELDNAME_groupId).is(groupId);
		Query query = new Query(c);
		Update update = new Update();
		update.set(GroupMemberRelationModel.FIELDNAME_delState, GroupMemberRelationModel.STATE_DISMISS);
		update.set(GroupMemberRelationModel.FIELDNAME_lastUpdateTime, System.currentTimeMillis());
		getMongoTemplate().updateMulti(query, update, getCollectionName(compId));
	}
}
